home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagn_r.zip / POINTERS.SWG / 0021_OOP Linked Lists.pas < prev    next >
Pascal/Delphi Source File  |  1994-08-24  |  9KB  |  343 lines

  1. Unit MgLinked;
  2.  
  3. interface
  4.  
  5. const
  6.  
  7.       { Error list. }
  8.       Succes       = $00;
  9.       Need_Mem     = $01;
  10.       Point_To_Nil = $02;
  11.  
  12. type
  13.  
  14.   DoubleLstPtr = ^DoubleLst;
  15.   DoubleLst    = record
  16.                    Serial       : longint;
  17.                    Size         : word;
  18.                    Addresse     : pointer;
  19.                    Next         : DoubleLstPtr;
  20.                    Previous     : DoubleLstPtr;
  21.                  end;
  22.  
  23.  
  24.   PDoubleLst = ^ODoubleLst;
  25.   ODoubleLst = object
  26.  
  27.     private
  28.     LastCodeErr : word;          {-- Last error.         --}
  29.  
  30.     public
  31.     TotalObj    : longint;       {-- Total obj allocate. --}
  32.     CurentObj   : DoubleLstPtr;  {-- Curent obj number.  --}
  33.  
  34.     constructor Init(var Install:boolean; Serial:longint; Size:word;
  35. Data:pointer);
  36.     {-- Initialise all variables, new curent.    ---}
  37.  
  38.     destructor Done;
  39.  
  40.     {--- get and clear the last err. ---}
  41.     function  LastError:word;
  42.  
  43.     {--- Seek to end and add an object.                            ---}
  44.     procedure Add(Size:word; Data:pointer);
  45.  
  46.     {--- Change the size of data of a object. 0 = change curent.   ---}
  47.     procedure ChangeSize(Serial:longint; NewSize : word);
  48.  
  49.     {--- Insert an object before the curent obj. 0 = insert curent pos ---}
  50.     procedure Insert(Serial:longint; Size:word; Data:pointer);
  51.  
  52.     {--- Delete an object from the list.  0 = delete curent.       ---}
  53.     procedure Delete(Serial:longint);
  54.  
  55.     {--- Pointe on next or end, etc.                               ---}
  56.     procedure SeekFirst;
  57.     procedure SeekLast;
  58.     procedure SeekNext;
  59.     procedure SeekPrevious;
  60.     procedure SeekNum(Serial:longint);
  61.  
  62.     {--- Move data from obj to user buffer                          ---}
  63.     {--- 0 = use curent object.                                     ---}
  64.     function MoveObjToPtr(Serial:longint; p:pointer):word;
  65.  
  66.     {--- Move user buffer to obj data.  obj data take ObjSize bytes ---}
  67.     {--- 0 = use curent object.                                     ---}
  68.     function MovePtrToObj(Serial:longint; p:pointer):word;
  69.  
  70.   end;
  71.  
  72. implementation
  73.  
  74. (****************************************************************************)
  75.  
  76.  procedure move(Src,Dst:pointer; Size:word);assembler;
  77.  asm
  78.     lds si,Src
  79.     les di,Dst
  80.     mov cx,Size
  81.     cld
  82.     rep movsb
  83.  end;
  84.  
  85.  
  86. (****************************************************************************)
  87.  
  88. constructor ODoubleLst.Init(var Install:boolean; Serial:longint; Size:word;
  89. Data:pointer);
  90. {-- Initialise all variables, new curent.    ---}
  91. begin
  92.      Install := false;
  93.      if Serial = 0 then exit;
  94.      New(CurentObj);
  95.      if CurentObj = nil then exit;
  96.      GetMem(CurentObj^.Addresse, Size);
  97.      if CurentObj^.Addresse = nil then
  98.      begin
  99.           LastCodeErr := Need_Mem;
  100.           exit;
  101.      end;
  102.  
  103.      CurentObj^.Next     := nil;
  104.      CurentObj^.Previous := nil;
  105.      CurentObj^.Size     := Size;
  106.      CurentObj^.Serial   := Serial;
  107.      move(Data, CurentObj^.Addresse, Size);
  108.  
  109.      TotalObj := 1;
  110.  
  111.      Install             := true;
  112.      LastCodeErr         := Succes;
  113. end;
  114.  
  115. (****************************************************************************)
  116.  
  117. destructor ODoubleLst.Done;
  118. {-- Initialise all variables, new curent.    ---}
  119. begin
  120.      repeat delete(0);
  121.      until (LastError <> Succes) or (TotalObj <= 0);
  122. end;
  123.  
  124. (****************************************************************************)
  125.  
  126. function  ODoubleLst.LastError:word;
  127. {--- get and clear the last err. ---}
  128. begin
  129.      LastError   := LastCodeErr;
  130.      LastCodeErr := 0;
  131. end;
  132.  
  133. (****************************************************************************)
  134.  
  135. procedure ODoubleLst.Add(Size:word; Data:pointer);
  136. {--- Seek to end and add an object.                            ---}
  137. begin
  138.      repeat SeekNext until LastError <> Succes; { SeekEnd }
  139.  
  140.      New(CurentObj^.Next);
  141.      if CurentObj^.Next = nil then
  142.      begin
  143.           LastCodeErr := Need_Mem;
  144.           exit;
  145.      end;
  146.  
  147.      GetMem(CurentObj^.Next^.Addresse, Size);
  148.      if CurentObj^.Next^.Addresse = nil then
  149.      begin
  150.           LastCodeErr := Need_Mem;
  151.           exit;
  152.      end;
  153.  
  154.      CurentObj^.Next^.Size := Size;
  155.  
  156.      { Store information data. }
  157.      move(Data, CurentObj^.Next^.Addresse, Size);
  158.  
  159.      { Increment the total number of reccords. }
  160.      inc(TotalObj);
  161.  
  162.      CurentObj^.Next^.Next := nil;
  163.      CurentObj^.Next^.Previous := CurentObj;
  164.  
  165.      LastCodeErr := Succes;
  166. end;
  167.  
  168. (****************************************************************************)
  169.  
  170. procedure ODoubleLst.ChangeSize(Serial:longint; NewSize : word);
  171. {--- Change the size of an object.                             ---}
  172. var p:pointer;
  173. begin
  174.      getmem(p,NewSize);
  175.      if p = nil then
  176.      begin
  177.           LastCodeErr := Need_mem;
  178.           exit;
  179.      end;
  180.      SeekNum(Serial);
  181.      move(CurentObj^.Addresse, p, NewSize);
  182.      freemem(CurentObj^.Addresse, CurentObj^.Size);
  183.      CurentObj^.Size := NewSize;
  184.      CurentObj^.Addresse := p;
  185.      LastCodeErr := Succes;
  186. end;
  187.  
  188. (****************************************************************************)
  189.  
  190. procedure ODoubleLst.Insert(Serial:longint; Size:word; Data:pointer);
  191. {--- Insert an object before the curent obj.                   ---}
  192. Var n:DoubleLstPtr;
  193. begin
  194.      new(n);
  195.      if n = nil then
  196.      begin
  197.           LastCodeErr := Need_mem;
  198.           exit;
  199.      end;
  200.      SeekNum(Serial);
  201.      getmem(n^.Addresse, Size);
  202.      if n^.Addresse = nil then
  203.      begin
  204.           LastCodeErr := Need_mem;
  205.           exit;
  206.      end;
  207.  
  208.      n^.Size := Size;
  209.      move(Data, n^.Addresse, Size);
  210.  
  211.      n^.Previous := CurentObj^.Previous;
  212.      n^.Next     := CurentObj;
  213.  
  214.      CurentObj^.Previous^.Next := n;
  215.      CurentObj^.Previous       := n;
  216.  
  217.      inc(TotalObj);
  218. end;
  219.  
  220. (****************************************************************************)
  221.  
  222. procedure ODoubleLst.Delete(Serial:longint);
  223. {--- Delete an object from the list.                           ---}
  224. begin
  225.      SeekNum(Serial);
  226.      if CurentObj^.Addresse <> nil then
  227.      begin
  228.            FreeMem(CurentObj^.Addresse,CurentObj^.Size);
  229.           CurentObj^.Addresse := nil;
  230.      end;
  231.  
  232.      CurentObj^.Next^.Previous := CurentObj^.Previous;
  233.      CurentObj^.Previous^.Next := CurentObj^.Next;
  234.  
  235.      if CurentObj <> nil then Dispose(CurentObj);
  236.      CurentObj := CurentObj^.Previous;
  237.  
  238.      dec(TotalObj);
  239. end;
  240.  
  241. (****************************************************************************)
  242.  
  243. procedure ODoubleLst.SeekLast;
  244. begin
  245.      repeat SeekNext until LastError <> Succes;
  246. end;
  247.  
  248. (****************************************************************************)
  249.  
  250. procedure ODoubleLst.SeekFirst;
  251. begin
  252.      repeat SeekPrevious until LastError <> Succes;
  253. end;
  254.  
  255. (****************************************************************************)
  256.  
  257. procedure ODoubleLst.SeekNext;
  258. begin
  259.      if CurentObj^.Next = nil then
  260.      begin
  261.           LastCodeErr := Point_To_Nil;
  262.           exit;
  263.      end;
  264.      CurentObj := CurentObj^.Next;
  265.      LastCodeErr := Succes;
  266. end;
  267.  
  268. (****************************************************************************)
  269.  
  270. procedure ODoubleLst.SeekPrevious;
  271. begin
  272.      if CurentObj^.Previous = nil then
  273.      begin
  274.           LastCodeErr := Point_To_Nil;
  275.           exit;
  276.      end;
  277.      CurentObj := CurentObj^.Previous;
  278.      LastCodeErr := Succes;
  279. end;
  280.  
  281. (****************************************************************************)
  282.  
  283. procedure ODoubleLst.SeekNum(Serial:longint);
  284. begin
  285.      if Serial = 0 then exit;
  286.      SeekFirst;
  287.      repeat
  288.  
  289.            SeekNext;
  290.  
  291.            if CurentObj^.Serial = Serial then
  292.            begin
  293.                 LastCodeErr := Succes;
  294.                 break;
  295.            end;
  296.  
  297.            if LastError <> Succes then
  298.            begin
  299.                 LastCodeErr := Point_To_Nil;
  300.                 break;
  301.            end
  302.            else continue;
  303.  
  304.      until false;
  305.  
  306. end;
  307.  
  308. (****************************************************************************)
  309.  
  310. function ODoubleLst.MoveObjToPtr(Serial:longint; p:pointer):word;
  311. {--- Move data from obj to user buffer                         ---}
  312. begin
  313.      SeekNum(Serial);
  314.      if (CurentObj^.Addresse = nil) or (p = nil) then
  315.      begin
  316.           LastCodeErr := Point_To_Nil;
  317.           exit;
  318.      end;
  319.      move(CurentObj^.Addresse, p, CurentObj^.Size);
  320.      LastCodeErr := Succes;
  321.      MoveObjToPtr := CurentObj^.Size;
  322. end;
  323.  
  324.  
  325. (****************************************************************************)
  326.  
  327. function ODoubleLst.MovePtrToObj(Serial:longint; p:pointer):word;
  328. {--- Move user buffer to obj data.  obj data take ObjSize bytes ---}
  329. begin
  330.      SeekNum(Serial);
  331.      if (CurentObj^.Addresse = nil) or (p = nil) then
  332.      begin
  333.           LastCodeErr := Point_To_Nil;
  334.           exit;
  335.      end;
  336.      move(p, CurentObj^.Addresse, CurentObj^.Size);
  337.      LastCodeErr := Succes;
  338.      MovePtrToObj := CurentObj^.Size;
  339. end;
  340.  
  341.  
  342. end.
  343.